#![allow(unused_imports,dead_code,unused_assignments)]
use axum::{
    extract::{Form, Query, Json, Multipart,DefaultBodyLimit},
    routing::{get,post},
    response::Response,
    body::{Body, Bytes},
    Router
};
use chrono::{NaiveDate,NaiveDateTime};
use crate::domain::CustOrderBean;
use crate::domain::CustOrderQueryRequest;
use crate::domain::my_date_format::DATE_FORMAT;
use crate::domain::my_date_time_format::DATE_TIME_FORMAT;

use crate::serviceimpl::cust_order_service::select_order_list as service_select_order_list;
use crate::serviceimpl::cust_order_service::get_order_count as service_get_order_count;
use crate::serviceimpl::cust_order_service::update_cust_order_status as service_update_cust_order_status;
use crate::serviceimpl::cust_order_service::delete_cust_order_with_order_items as service_delete_cust_order_with_order_items;
use crate::serviceimpl::order_item_service::list_my_order_items as service_list_my_order_items;
use crate::utils::excel_util::export_excel_workbook_with_image;
use crate::utils::pdf_util::export_pdf_with_images;
use serde::{Deserialize};
use serde_json::{Value,Map};
use std::fs;
use tower_http::{trace::TraceLayer};

#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CustOrderStatusCustRequest {
	pub id: i64,
	pub statusId: i64,
}

#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CustOrderListWithStatusCustRequest {
	pub page: i32,
	pub rows: i32,
	pub status_id:i64,
}

#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct OrderItemRequest {
	pub id: Option<i64>,
	pub name: Option<String>,
	pub active: Option<bool>,
	pub price: Option<f64>,
	pub amount: Option<i32>,
	pub goods_id: Option<i64>,
	pub cust_order_id: Option<i64>,
}

#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CustOrderRequest {
	pub id: Option<i64>,
	pub name: Option<String>,
	pub active: Option<bool>,
	pub total: Option<f64>,
	pub amount: Option<i32>,
	pub status_id: Option<i64>,
	pub pay_type_id: Option<i64>,
	pub phone: Option<String>,
	pub address: Option<String>,
	pub order_date_time: Option<String>,
	pub user_id: Option<i64>,
}

pub fn admin_cust_order_cust_controller() -> Router {
	Router::new()
	.route("/order_list", post(admin_order_list))
	.route("/updateCustOrderStatus", post(update_cust_order_status))
	.route("/listMyOrderItems", post(list_my_order_items))
	.route("/deleteCustOrderWithOrderItems", post(delete_cust_order_with_order_items))
	.layer(DefaultBodyLimit::max(2*1024*1024))
	.layer(TraceLayer::new_for_http())
}

pub async fn admin_order_list(Json(cust_order_list_with_status_cust_request):Json<CustOrderListWithStatusCustRequest>) ->String {
    let status_id:i64 = cust_order_list_with_status_cust_request.status_id;
    let pageNumber:i32 = cust_order_list_with_status_cust_request.page;
    let pageSize:i32 = cust_order_list_with_status_cust_request.rows;;
	let cust_orders = service_select_order_list(status_id,pageNumber).await;
	let totalCount:i32 = service_get_order_count(status_id).await.unwrap().count_num as i32;
    let totalPage:i32 = (totalCount as f64/pageSize as f64).ceil() as i32;

	match cust_orders {
		Err(_) => {
			println!("Error!");
			r#"{  "rows": null,  "success": true}"#.to_string()
		},
		Ok(cust_orders) => {
			let json = serde_json::to_string_pretty(&cust_orders).unwrap();
			//println!("{}", json);

			let mut map = Map::new();
			map.insert("success".to_string(), Value::from(true));
			map.insert("pageNumber".to_string(), Value::from(pageNumber));
			map.insert("pageSize".to_string(), Value::from(pageSize));
			map.insert("totalCount".to_string(), Value::from(totalCount));
			map.insert("totalPage".to_string(), Value::from(totalPage));
			map.insert(
				"rows".to_string(),
				serde_json::from_str(&json).unwrap(),
			);

			let resultjson = serde_json::to_string_pretty(&map).unwrap();
			//println!("{}", resultjson);
			return resultjson;
		}
	}
}

pub async fn update_cust_order_status(Json(cust_order_status_cust_request):Json<CustOrderStatusCustRequest>) ->String {
	let id = cust_order_status_cust_request.id;
	let status_id = cust_order_status_cust_request.statusId;

	let _result = service_update_cust_order_status(id,status_id).await;
	match _result {
		Err(_) => {
			r#"{  "rows": null,  "success": true}"#.to_string()
		},
		Ok(_result) => {
			let mut map = Map::new();
			map.insert("success".to_string(), Value::from(true));
			map.insert(
				"rows".to_string(),
				Value::from(""),
			);

			let resultjson = serde_json::to_string_pretty(&map).unwrap();
			return resultjson;
		}
	}
}

pub async fn list_my_order_items(Json(order_item_request):Json<OrderItemRequest>) ->String {
    let cust_order_id = order_item_request.cust_order_id.unwrap_or_default();
    if cust_order_id == 0 {
        return r#"{  "rows": null,  "success": true}"#.to_string();
    }
	let order_items = service_list_my_order_items(cust_order_id).await;
	match order_items {
		Err(_) => {
			println!("Error!");
			r#"{  "rows": null,  "success": true}"#.to_string()
		},
		Ok(order_items) => {
			let json = serde_json::to_string_pretty(&order_items).unwrap();
			//println!("{}", json);

			let mut map = Map::new();
			map.insert("success".to_string(), Value::from(true));
			map.insert(
				"rows".to_string(),
				serde_json::from_str(&json).unwrap(),
			);

			let resultjson = serde_json::to_string_pretty(&map).unwrap();
			//println!("{}", resultjson);
			return resultjson;
		}
	}
}

pub async fn delete_cust_order_with_order_items(Form(cust_order_request):Form<CustOrderRequest>) ->String {
	let id = cust_order_request.id.unwrap_or_default();
	let _result = service_delete_cust_order_with_order_items(id).await;
	match _result {
		Err(_) => {
			r#"{  "rows": null,  "success": true}"#.to_string()
		},
		Ok(_result) => {
			let mut map = Map::new();
			map.insert("success".to_string(), Value::from(true));
			map.insert(
				"rows".to_string(),
				Value::from(""),
			);

			let resultjson = serde_json::to_string_pretty(&map).unwrap();
			return resultjson;
		}
	}
}
